#include "lv_conf.h"
#include "main.h"

void SPI_SendData(unsigned char i)
{
    unsigned char n;

    for (n = 0; n < 8; n++)
    {
        if (i & 0x80)
            SPI_DI_H;
        else
            SPI_DI_L;
        i <<= 1;

        SPI_CLK_L;
        swm_delay_us(1);
        SPI_CLK_H;
        swm_delay_us(1);
    }
}
void SPI_WriteComm(unsigned char i)
{
    SPI_CS_L;

    SPI_DI_L;

    SPI_CLK_L;
    swm_delay_us(1);
    SPI_CLK_H;
    swm_delay_us(1);

    SPI_SendData(i);

    SPI_CS_H;
}

void SPI_WriteData(unsigned char i)
{
    SPI_CS_L;

    SPI_DI_H;

    SPI_CLK_L;
    swm_delay_us(1);
    SPI_CLK_H;
    swm_delay_us(1);

    SPI_SendData(i);

    SPI_CS_H;
}

void LCD_SPI_Init(void)
{
    GPIO_Init(GPIOM, PIN16, 1, 0, 0); //reset
    GPIO_Init(GPIOM, PIN20, 1, 0, 0); //cs
    GPIO_Init(GPIOA, PIN10, 1, 0, 0); //scl
    GPIO_Init(GPIOA, PIN9, 1, 0, 0);  //sda

    RES_H;
    swm_delay_ms(20);
    RES_L;
    swm_delay_ms(300);
    RES_H;
    swm_delay_ms(160);

    //360x640
    //	SPI_WriteComm(0x11);
    //	swm_delay_ms(120);

    SPI_WriteComm(0xFF); //System Function Command Table2
    SPI_WriteData(0x77);
    SPI_WriteData(0x01);
    SPI_WriteData(0x00);
    SPI_WriteData(0x00);
    SPI_WriteData(0x10);
    swm_delay_ms(5);

    SPI_WriteComm(0xC0); //Display Line Setting
    SPI_WriteData(0x4F); //640
    SPI_WriteData(0x00);
    swm_delay_ms(5);

    SPI_WriteComm(0xC1);
    SPI_WriteData(0x07);
    SPI_WriteData(0x02);
    swm_delay_ms(5);

    SPI_WriteComm(0xC2);
    SPI_WriteData(0x31);
    SPI_WriteData(0x05);
    swm_delay_ms(5);

    SPI_WriteComm(0xB0);
    SPI_WriteData(0x00);
    SPI_WriteData(0x0A);
    SPI_WriteData(0x11);
    SPI_WriteData(0x0C);
    SPI_WriteData(0x10);
    SPI_WriteData(0x05);
    SPI_WriteData(0x00);
    SPI_WriteData(0x08);
    SPI_WriteData(0x08);
    SPI_WriteData(0x1F);
    SPI_WriteData(0x07);
    SPI_WriteData(0x13);
    SPI_WriteData(0x10);
    SPI_WriteData(0xA9);
    SPI_WriteData(0x30);
    SPI_WriteData(0x18);
    swm_delay_ms(5);

    SPI_WriteComm(0xB1);
    SPI_WriteData(0x00);
    SPI_WriteData(0x0B);
    SPI_WriteData(0x11);
    SPI_WriteData(0x0D);
    SPI_WriteData(0x0F);
    SPI_WriteData(0x05);
    SPI_WriteData(0x02);
    SPI_WriteData(0x07);
    SPI_WriteData(0x06);
    SPI_WriteData(0x20);
    SPI_WriteData(0x05);
    SPI_WriteData(0x15);
    SPI_WriteData(0x13);
    SPI_WriteData(0xA9);
    SPI_WriteData(0x30);
    SPI_WriteData(0x18);
    swm_delay_ms(5);

    SPI_WriteComm(0xFF);
    SPI_WriteData(0x77);
    SPI_WriteData(0x01);
    SPI_WriteData(0x00);
    SPI_WriteData(0x00);
    SPI_WriteData(0x11);
    swm_delay_ms(5);

    SPI_WriteComm(0xB0);
    SPI_WriteData(0x53);
    swm_delay_ms(5);

    SPI_WriteComm(0xB1);
    SPI_WriteData(0x60);
    swm_delay_ms(5);

    SPI_WriteComm(0xB2);
    SPI_WriteData(0x07);
    swm_delay_ms(5);

    SPI_WriteComm(0xB3);
    SPI_WriteData(0x80);
    swm_delay_ms(5);

    SPI_WriteComm(0xB5);
    SPI_WriteData(0x49);
    swm_delay_ms(5);

    SPI_WriteComm(0xB7);
    SPI_WriteData(0x85);
    swm_delay_ms(5);

    SPI_WriteComm(0xB8);
    SPI_WriteData(0x21);
    swm_delay_ms(5);

    SPI_WriteComm(0xC1);
    SPI_WriteData(0x78);
    swm_delay_ms(5);

    SPI_WriteComm(0xC2);
    SPI_WriteData(0x78);
    swm_delay_ms(100);

    SPI_WriteComm(0xE0);
    SPI_WriteData(0x00);
    SPI_WriteData(0x00);
    SPI_WriteData(0x02);
    swm_delay_ms(5);

    SPI_WriteComm(0xE1);
    SPI_WriteData(0x03);
    SPI_WriteData(0xA0);
    SPI_WriteData(0x00);
    SPI_WriteData(0x00);
    SPI_WriteData(0x02);
    SPI_WriteData(0xA0);
    SPI_WriteData(0x00);
    SPI_WriteData(0x00);
    SPI_WriteData(0x00);
    SPI_WriteData(0x33);
    SPI_WriteData(0x33);
    swm_delay_ms(5);

    SPI_WriteComm(0xE2);
    SPI_WriteData(0x22);
    SPI_WriteData(0x22);
    SPI_WriteData(0x33);
    SPI_WriteData(0x33);
    SPI_WriteData(0x88);
    SPI_WriteData(0xA0);
    SPI_WriteData(0x00);
    SPI_WriteData(0x00);
    SPI_WriteData(0x87);
    SPI_WriteData(0xA0);
    SPI_WriteData(0x00);
    SPI_WriteData(0x00);
    swm_delay_ms(5);

    SPI_WriteComm(0xE3);
    SPI_WriteData(0x00);
    SPI_WriteData(0x00);
    SPI_WriteData(0x22);
    SPI_WriteData(0x22);
    swm_delay_ms(5);

    SPI_WriteComm(0xE4);
    SPI_WriteData(0x44);
    SPI_WriteData(0x44);
    swm_delay_ms(5);

    SPI_WriteComm(0xE5);
    SPI_WriteData(0x04);
    SPI_WriteData(0x84);
    SPI_WriteData(0xA0);
    SPI_WriteData(0xA0);
    SPI_WriteData(0x06);
    SPI_WriteData(0x86);
    SPI_WriteData(0xA0);
    SPI_WriteData(0xA0);
    SPI_WriteData(0x08);
    SPI_WriteData(0x88);
    SPI_WriteData(0xA0);
    SPI_WriteData(0xA0);
    SPI_WriteData(0x0A);
    SPI_WriteData(0x8A);
    SPI_WriteData(0xA0);
    SPI_WriteData(0xA0);
    swm_delay_ms(5);

    SPI_WriteComm(0xE6);
    SPI_WriteData(0x00);
    SPI_WriteData(0x00);
    SPI_WriteData(0x22);
    SPI_WriteData(0x22);
    swm_delay_ms(5);

    SPI_WriteComm(0xE7);
    SPI_WriteData(0x44);
    SPI_WriteData(0x44);
    swm_delay_ms(5);

    SPI_WriteComm(0xE8);
    SPI_WriteData(0x03);
    SPI_WriteData(0x83);
    SPI_WriteData(0xA0);
    SPI_WriteData(0xA0);
    SPI_WriteData(0x05);
    SPI_WriteData(0x85);
    SPI_WriteData(0xA0);
    SPI_WriteData(0xA0);
    SPI_WriteData(0x07);
    SPI_WriteData(0x87);
    SPI_WriteData(0xA0);
    SPI_WriteData(0xA0);
    SPI_WriteData(0x09);
    SPI_WriteData(0x89);
    SPI_WriteData(0xA0);
    SPI_WriteData(0xA0);
    swm_delay_ms(5);

    SPI_WriteComm(0xEB);
    SPI_WriteData(0x00);
    SPI_WriteData(0x01);
    SPI_WriteData(0xE4);
    SPI_WriteData(0xE4);
    SPI_WriteData(0x88);
    SPI_WriteData(0x00);
    SPI_WriteData(0x40);
    swm_delay_ms(5);

    SPI_WriteComm(0xEC);
    SPI_WriteData(0x3C);
    SPI_WriteData(0x01);
    swm_delay_ms(5);

    SPI_WriteComm(0xED);
    SPI_WriteData(0xAB);
    SPI_WriteData(0x89);
    SPI_WriteData(0x76);
    SPI_WriteData(0x54);
    SPI_WriteData(0x02);
    SPI_WriteData(0xFF);
    SPI_WriteData(0xFF);
    SPI_WriteData(0xFF);
    SPI_WriteData(0xFF);
    SPI_WriteData(0xFF);
    SPI_WriteData(0xFF);
    SPI_WriteData(0x20);
    SPI_WriteData(0x45);
    SPI_WriteData(0x67);
    SPI_WriteData(0x98);
    SPI_WriteData(0xBA);
    swm_delay_ms(5);
    //	SPI_WriteComm(0x3A);
    //	SPI_WriteData(0x55);
    //	swm_delay_ms(100);
    //	SPI_WriteComm(0x29);

    SPI_WriteComm(0x3a);
    SPI_WriteData(0x77);

    SPI_WriteComm(0x36);
    SPI_WriteData(0x00);

    SPI_WriteComm(0x11);
    swm_delay_ms(120);
    SPI_WriteComm(0x29);
    SPI_WriteComm(0x35);
    SPI_WriteData(0x00);
}

void lcd_memory_init(void)
{
    SDRAM_InitStructure SDRAM_InitStruct;

    PORT->PORTP_SEL0 = 0xAAAAAAAA; //PP0-23 => ADDR0-23
    PORT->PORTP_SEL1 &= ~0x00000F0F;
    PORT->PORTP_SEL1 |= 0x00000A0A;

    PORT->PORTM_SEL0 = 0xAAAAAAAA; //PM0-15 => DATA15-0
    PORT->PORTM_INEN |= 0xFFFF;
    //PM17 => WEN,PM19 => SDRAM_CSN,PM21 => SDRAM_CKE
    PORT->PORTM_SEL1 &= ~0xFFF;
    PORT->PORTM_SEL1 |= 0x888;

    SDRAM_InitStruct.CellSize = SDRAM_CELLSIZE_64Mb;
    SDRAM_InitStruct.CellBank = SDRAM_CELLBANK_4;
    SDRAM_InitStruct.CellWidth = SDRAM_CELLWIDTH_16;
    SDRAM_InitStruct.CASLatency = SDRAM_CASLATENCY_2;
    SDRAM_InitStruct.TimeTMRD = SDRAM_TMRD_3;
    SDRAM_InitStruct.TimeTRRD = SDRAM_TRRD_2;
    SDRAM_InitStruct.TimeTRAS = SDRAM_TRAS_6;
    SDRAM_InitStruct.TimeTRC = SDRAM_TRC_8;
    SDRAM_InitStruct.TimeTRCD = SDRAM_TRCD_3;
    SDRAM_InitStruct.TimeTRP = SDRAM_TRP_3;
    SDRAM_Init(&SDRAM_InitStruct);
}

void lcd_rgb_init(void)
{
    LCD_InitStructure LCD_initStruct;

    LCD_SPI_Init();

    GPIO_Init(GPIOM, PIN20, 1, 0, 0); //复位
    GPIO_ClrBit(GPIOM, PIN20);
    swm_delay_ms(1);
    GPIO_SetBit(GPIOM, PIN20);

    GPIO_Init(GPIOM, PIN18, 1, 0, 0); //背光控制

    PORT->PORTN_SEL0 = 0xAAAAAAAA; //GPION.0~15  LCD_DATA0~15
    PORT->PORTN_SEL1 = 0xAA;

    LCD_initStruct.HnPixel = LCD_HOR;
    LCD_initStruct.VnPixel = LCD_VER;
    LCD_initStruct.Hfp = 40;
    LCD_initStruct.Hbp = 60;
    LCD_initStruct.Vfp = 20;
    LCD_initStruct.Vbp = 20;
    LCD_initStruct.ClkDiv = LCD_CLKDIV_12;
    LCD_initStruct.ClkAlways = 0;
    LCD_initStruct.SamplEdge = LCD_SAMPLEDGE_FALL;
    LCD_initStruct.HsyncWidth = LCD_HSYNC_3DOTCLK;
    LCD_initStruct.IntEOTEn = 1;
    LCD_Init(LCD, &LCD_initStruct);
}

void LCD_Handler(void)
{
    LCD_INTClr(LCD);
    LCD_Start(LCD);
}
